/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.infotypes;

import java.util.ArrayList;

/**
 * This class holds the set of elements, which can be seen by the coach. These
 * are the teammates (<code>ownPlayers</code>), the opponents (<code>
 * otherPlayers</code>), and the ball. 
 */
public class CoachVisualInfo extends Info {

	/**
	 * A list contain all seen teammates.
	 */
	private ArrayList<CoachPlayerInfo> ownPlayers = new ArrayList<CoachPlayerInfo>();

	/**
	 * A list containing all seen opponents.
	 */
	private ArrayList<CoachPlayerInfo> otherPlayers = new ArrayList<CoachPlayerInfo>();

	/**
	 * The seen ball.
	 */
	private CoachBallInfo ball = new CoachBallInfo(0, 0, 0, 0, 0);

	/**
	 * The name of the own team.
	 */
	private String ownTeamName = null;

	/**
	 * The opponents team name.
	 */
	private String otherTeamName = null;

	/**
	 * CoachVI consists of seen (global) players and ball! It needs the
	 * ownTeam-Name to identify own players (own / other players perceived)
	 * 
	 * @param iCycle -
	 *            when was the VI received
	 * @param ownTeamName -
	 *            to check, which agents belong to own or other team
	 */
	public CoachVisualInfo(int iCycle, String ownTeamName) {
		super(iCycle);
		this.infoType = Info.TYPE_COACHVI;
		this.ownTeamName = ownTeamName;
	}

	/**
	 * Resets the lists for own and opponents seen players, in order to
	 * reuse them.
	 */
	public void reset() {
		for (int i = 0; i < this.ownPlayers.size();)
			this.ownPlayers.remove(0);
		for (int i = 0; i < this.otherPlayers.size();)
			this.otherPlayers.remove(0);
	}

	/**
	 * Creates a new CoachPlayer and adds him to the list (own or other,
	 * depending on the team) Warning: do not buffer, always create a new
	 * player, because they are used directly in coach-tactics
	 * 
	 * @param cycle -
	 *            the cycle
	 * @param dyPos -
	 *            the y-position in robocup-coordinates, has to be changed with
	 *            x in our coordinate-system
	 * @param dxPos -
	 *            the x-position in robocup-coordinates, has to be changed with
	 *            y in our coordinate-system
	 * @param dyVel -
	 *            the y velocity, has to be changed with x-velocity according to
	 *            our changed coordinate system
	 * @param dxVel -
	 *            the x velocity, has to be changed with y-velocity according to
	 *            our changed coordinate system
	 * @param iNum -
	 *            the players tricot number
	 * @param dBodyAngel -
	 *            his body angle
	 * @param dHeadAngel -
	 *            his head-angle
	 * @param dPointDir -
	 *            the direction he points to
	 * @param tackle -
	 *            is tackling (blocked?)
	 */
	public void addPlayer(String team, boolean own, int cycle, double dyPos,
			double dxPos, double dyVel, double dxVel, int iNum,
			double dBodyAngle, double dHeadAngle, double dPointDir,
			boolean goalie, boolean tackle) {

		CoachPlayerInfo cpi = new CoachPlayerInfo("", 0, 0, 0, 0, 0, 0, 0, 0,
				0, false, false);
		cpi.setTeamName(team);
		cpi.setCycle(cycle);
		cpi.setYPos(dxPos);
		cpi.setXPos(dyPos);
		cpi.setYSpeed(dxVel);
		cpi.setXSpeed(dyVel);
		cpi.setPlayerNumber(iNum);
		cpi.setBodyAngle(dBodyAngle);
		cpi.setNeckAngle(dHeadAngle);
		cpi.setPointDirection(dPointDir);
		cpi.setGoalie(goalie);
		cpi.setTackle(tackle);

		if (own)
			addOwn(cpi);
		else
			addOther(cpi);
	}

	/**
	 * Adds own player to the list
	 * 
	 * @param info -
	 *            a player
	 */
	private void addOwn(CoachPlayerInfo info) {
		if (this.cycle == 0)
			this.cycle = info.getCycle();
		this.ownPlayers.add(info);
	}

	/**
	 * Adds other player to the list
	 * 
	 * @param info -
	 *            a player
	 */
	private void addOther(CoachPlayerInfo info) {
		if (this.cycle == 0)
			this.cycle = info.getCycle();
		this.otherPlayers.add(info);
	}

	/**
	 * Creates a new ball with given values
	 * 
	 * @param cycle -
	 *            the game cycle
	 * @param dyPos -
	 *            its y position, which will be x in out coordinates
	 * @param dxPos -
	 *            its x position, which will be y in out coordinates
	 * @param dyVel -
	 *            its y velocity, which will be y in out coordinates
	 * @param dxVel -
	 *            its x velocity, which will be y in out coordinates
	 */
	public void setBall(int cycle, double dyPos, double dxPos, double dyVel,
			double dxVel) {
		this.ball = new CoachBallInfo(0, 0, 0, 0, 0);
		this.ball.setCycle(cycle);
		this.ball.setYPos(dxPos);
		this.ball.setXPos(dyPos);
		this.ball.setYSpeed(dxVel);
		this.ball.setXSpeed(dyVel);
	}

	/**
	 * @return Returns the ball.
	 */
	public CoachBallInfo getCoachBall() {
		return this.ball;
	}

	/**
	 * @return Returns the otherPlayers.
	 */
	public CoachPlayerInfo[] getOtherPlayers() {
		return (this.otherPlayers.toArray(new CoachPlayerInfo[this.otherPlayers
				.size()]));
	}

	/**
	 * @return Returns the ownPlayers.
	 */
	public CoachPlayerInfo[] getOwnPlayers() {
		return (this.ownPlayers.toArray(new CoachPlayerInfo[this.ownPlayers
				.size()]));
	}

	/**
	 * @return Returns the otherTeamName.
	 */
	public String getOtherTeamName() {
		return this.otherTeamName;
	}

	/**
	 * @param otherTeamName
	 *            The otherTeamName to set.
	 */
	public void setOtherTeamName(String otherTeamName) {
		this.otherTeamName = otherTeamName;
	}

	/**
	 * @return Returns the ownTeamName.
	 */
	public String getOwnTeamName() {
		return this.ownTeamName;
	}
}
